﻿//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Collections.ObjectModel;
using System.Text;

namespace Microsoft.ResourceManagement.Samples.ResourceManagementClient.ResourceManagement
{

    public class ResourceManagementObject
    {
        private String objectName;
        private String objectId;
        private Dictionary<String, ResourceManagementAttribute> attributes;
        private Dictionary<String, bool> changedAttributes;
        /// <summary>
        /// Constructs a new object of type objectName
        /// </summary>
        /// <param name="objectName">The type of the object.</param>
        public ResourceManagementObject(String objectName)
            : this(String.Empty, objectName)
        {

        }
        /// <summary>
        /// Constructs a new object of type objectName and id objectId
        /// </summary>
        /// <param name="objectId">The object id</param>
        /// <param name="objectName">The type of the object.</param>
        public ResourceManagementObject(String objectId, String objectName)
        {
            this.objectId = objectId;
            this.objectName = objectName;
            attributes = new Dictionary<string, ResourceManagementAttribute>();
            changedAttributes = new Dictionary<string, bool>();
        }

        /// <summary>
        /// The type of the object
        /// </summary>
        public String ObjectName
        {
            get
            {
                return objectName;
            }
        }

        /// <summary>
        /// The object id.
        /// </summary>
        public String ObjectId
        {
            get
            {
                return objectId;
            }
        }

        /// <summary>
        /// The reosurce management attribute whose name is provided.
        /// </summary>
        /// <param name="attributeName">The name of the attribute.</param>
        /// <returns>The attribute or null if not found.</returns>
        public ResourceManagementAttribute this[String attributeName]
        {
            get
            {
                if (null == attributeName)
                {
                    throw new ArgumentNullException("attributeName");
                }
                ResourceManagementAttribute outAttrib = null;
                attributes.TryGetValue(attributeName, out outAttrib);
                if (null == outAttrib)
                {
                    return null;
                }
                else
                {
                    return outAttrib;
                }
            }
            set
            {
                if (null == attributeName)
                {
                    throw new ArgumentNullException("attributeName");
                }
                attributes[attributeName] = value;
                changedAttributes[attributeName] = true;
            }
        }

        /// <summary>
        /// Returns a list of all known attribute names in this object.
        /// </summary>
        public ReadOnlyCollection<String> AttributeNames
        {
            get
            {
                List<String> retList = new List<string>();
                foreach(String key in this.attributes.Keys)
                {
                    retList.Add(key);
                }
                return new ReadOnlyCollection<string>(retList);
            }
        }

        /// <summary>
        /// True if the given attribute has changed.
        /// </summary>
        /// <param name="attributeName">The name of the attribute to check</param>
        /// <returns>True if changed</returns>
        public bool IsChanged(String attributeName)
        {
            if (null == attributeName)
            {
                throw new ArgumentNullException("attributeName");
            }
            return changedAttributes.ContainsKey(attributeName) || attributes[attributeName].IsValueChanged;
        }

        public override string ToString()
        {
            return this.ObjectName + "@" + this.ObjectId;
        }

        /// <summary>
        /// Resets the list of changed attributes and marks each attribute as unchanged.
        /// Does not change the value.
        /// </summary>
        public void ClearIsChanged()
        {
            this.changedAttributes.Clear();
            lock (this.attributes)
            {
                foreach (ResourceManagementAttribute attrib in this.attributes.Values)
                {
                    attrib.ClearIsChanged();
                }
            }
        }
    }
}
